// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "remesh_self_intersections.h"
#include "SelfIntersectMesh.h"
#include "assign_scalar.h"
#include "../../C_STR.h"
#include "../../remove_unreferenced.h"
#include <list>
#include <iostream>

template <
  typename DerivedV,
  typename DerivedF,
  typename DerivedVV,
  typename DerivedFF,
  typename DerivedIF,
  typename DerivedJ,
  typename DerivedIM>
IGL_INLINE void igl::copyleft::cgal::remesh_self_intersections(
  const Eigen::MatrixBase<DerivedV> & V,
  const Eigen::MatrixBase<DerivedF> & F,
  const RemeshSelfIntersectionsParam & params,
  Eigen::PlainObjectBase<DerivedVV> & VV,
  Eigen::PlainObjectBase<DerivedFF> & FF,
  Eigen::PlainObjectBase<DerivedIF> & IF,
  Eigen::PlainObjectBase<DerivedJ> & J,
  Eigen::PlainObjectBase<DerivedIM> & IM)
{
  typedef typename DerivedV::Scalar VScalar;
  if(params.detect_only && ! std::is_same<VScalar,CGAL::Epeck::FT>::value)
  {
    //// This is probably a terrible idea, but CGAL is throwing floating point
    //// exceptions.

//#ifdef __APPLE__
//#define IGL_THROW_FPE 11
//    const auto & throw_fpe = [](int e)
//    {
//      throw "IGL_THROW_FPE";
//    };
//    signal(SIGFPE,throw_fpe);
//#endif

    typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
    typedef
      SelfIntersectMesh<
        Kernel,
        DerivedV,
        DerivedF,
        DerivedVV,
        DerivedFF,
        DerivedIF,
        DerivedJ,
        DerivedIM>
      SelfIntersectMeshK;
    SelfIntersectMeshK SIM(V,F,params,VV,FF,IF,J,IM);

//#ifdef __APPLE__
//    signal(SIGFPE,SIG_DFL);
//#endif

  }else
  {
    typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
    typedef
      SelfIntersectMesh<
        Kernel,
        DerivedV,
        DerivedF,
        DerivedVV,
        DerivedFF,
        DerivedIF,
        DerivedJ,
        DerivedIM>
      SelfIntersectMeshK;
    SelfIntersectMeshK SIM(V,F,params,VV,FF,IF,J,IM);
  }
}

template <
  typename DerivedV,
  typename DerivedF,
  typename DerivedVV,
  typename DerivedFF,
  typename DerivedIF,
  typename DerivedJ>
IGL_INLINE void igl::copyleft::cgal::remesh_self_intersections(
  const Eigen::MatrixBase<DerivedV> & V,
  const Eigen::MatrixBase<DerivedF> & F,
  const RemeshSelfIntersectionsParam & params,
  Eigen::PlainObjectBase<DerivedVV> & VV,
  Eigen::PlainObjectBase<DerivedFF> & FF,
  Eigen::PlainObjectBase<DerivedIF> & IF,
  Eigen::PlainObjectBase<DerivedJ> & J)
{
  assert(!params.detect_only && "detect_only must be false");
  assert(params.stitch_all   && "stitch_all must be true (I think)");
  {
    using FFScalar = typename DerivedFF::Scalar;
    // enforced by assertion: params.stitch_all = true; 
    Eigen::Matrix<CGAL::Epeck::FT,Eigen::Dynamic,3,DerivedVV::IsRowMajor> Vr;
    {
      Eigen::VectorXi I;
      igl::copyleft::cgal::remesh_self_intersections(
          V, F, params, Vr, FF, IF, J, I);
      assert(I.size() == Vr.rows());
      // Merge coinciding vertices into non-manifold vertices.
      std::for_each(FF.data(),FF.data()+FF.size(),[&I](FFScalar& a){a=I[a];});
    }
    // Remove unreferenced vertices and assign to output
    {
      Eigen::VectorXi ruI,ruJ;
      igl::remove_unreferenced(Vr.rows(), FF, ruI, ruJ);
      std::for_each(
        FF.data(),FF.data()+FF.size(),[&ruI](FFScalar& a){a=ruI(a);});
      VV.resize(ruJ.size(),3);
      for(int i = 0;i<ruJ.size();i++)
      {
        for(int j = 0;j<3;j++)
        {
          assign_scalar(Vr(ruJ(i),j),params.slow_and_more_precise_rounding,VV(i,j));
        }
      }
    }
  }
}

#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#include <cstdint>
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<std::ptrdiff_t,-1,2,0,-1,2>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,3,0,-1,3> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,3,0,-1,3> >&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,2,0,-1,2> >&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,3,0,-1,3>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,3,0,-1,3> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,3,1,-1,3>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,3,1,-1,3> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,3,0,-1,3> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,3,0,-1,3> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,1,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,1,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,Eigen::Matrix<int,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
#endif
